<?php
namespace app\mini_api\controller;

class WxPayNotify
{
    public function fromXml($xml)
    {   
        if(!$xml){
            throw new WxPayException("xml数据异常！");
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $this->values;
    }

    public function payCallback()
    {
        //接收微信返回的数据数据,返回的xml格式
        $xmlData = file_get_contents('php://input');
        //将xml格式转换为数组
        $data = $this->fromXml($xmlData);

        $logs['create_at'] = time();
        $logs['data'] = json_encode($data);
        db('WxPayLogs')->insert($logs);

        //为了防止假数据，验证签名是否和返回的一样。
        //记录一下，返回回来的签名，生成签名的时候，必须剔除sign字段。
        $sign = $data['sign'];
        unset($data['sign']);
        if($sign == $this->sign($data))
        {

            //签名验证成功后，判断返回微信返回的
            if ($data['result_code'] == 'SUCCESS' && $data['return_code'] == "SUCCESS")
            {

                
                //根据返回的订单号做业务逻辑  
                
                $map = [
                    'out_trade_no' => $data['out_trade_no']
                ];
                $trade = db('trade')->where($map)->find();

                if($trade['paid_time'] == 0)
                {
                    $user = db('Member')->where(['id'=>$trade['member_id']])->find();
                    // $person = $user['realname'] != '' && $user['id_card'] != '' ? true : false;
                    // $company = $user['company_name'] != '' && $user['company_code'] != '' ? true : false;
                    $name = $trade['type'] == '个人' ? $user['realname'] : $user['company_contact'];

                    $status = 100; // 10表示个人待实名
                    
                    $user['status'] = $status;
                    db('Member')->update($user);

                    $tData = [
                        'paid_time' => time(),
                        'status' => $status
                    ];
                    db('Trade')->where($map)->update($tData);

                    # 生成购买广告
                    $aData = [
                        'pay_time' => date('Y-m-d'),
                        'text' => xinghao($user['username'],3,4).'开通了 '.$trade['title']
                    ];
                    db('AdList')->insert($aData);
                }
                    
                


                //处理完成之后，告诉微信成功结果！
                echo '<xml>
                        <return_code><![CDATA[SUCCESS]]></return_code>
                        <return_msg><![CDATA[OK]]></return_msg>
                        </xml>';
                exit(); 
            }
            else
            {
                $wx['content'] = '错误信息'.$data['return_msg'];
                db('wx')->insert($wx); 
            }
        }
        else
        {
            $wx['content'] = '签名验证失败';
            db('wx')->insert($wx); 
        }

    }

    private function getxml($xml)
    {
        $p = xml_parser_create();
        xml_parse_into_struct($p, $xml, $vals, $index);
        xml_parser_free($p);
        $data = '';
        foreach ($index as $k => $v) {
            if($k = 'xml' || $k == 'XML') continue;
            $tag = $vals[$v[0]]['tag'];
            $v = $vals[$v[0]]['value'];
            $data[$tag] = $v;
        }
        return $data;
    }
    private function sign($data)
    {
        $key = '20232a613b1y9b54c46734ed48bbced5';
        //签名步骤一：按字典序排序参数
        ksort($data);
        $buff = '';
        foreach ($data as $k => $v) {
            if($k != 'sign' && $v != '' && !is_array($v)){
                $buff .= $k . '=' . $v . '&';
            }
        }
        $buff = trim($buff,'&');

        //签名步骤二：在string后加入KEY
        $string = $buff . "&key=".$key;

        //签名步骤三：MD5加密或者HMAC-SHA256
        $string = md5($string);
        
        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

}
